package com.cloud.apis.user.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.cloud.apis.core.model.Dict;
import com.cloud.apis.core.model.PageData;
import com.cloud.apis.core.model.User;
import com.cloud.apis.core.web.R;
import com.cloud.apis.organization.pojo.form.TransferForm;
import com.cloud.apis.oss.controller.CosController;
import com.cloud.apis.user.pojo.form.*;
import com.cloud.apis.user.pojo.vo.UserInfoVo;
import com.cloud.apis.user.service.IUserService;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.validator.constraints.Range;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.HashMap;

/**
 * 用户相关API接口
 *
 * @Author YinXi
 * @Versin 1.0.0
 * @Date 2024/3/20
 */
@RestController
@RequestMapping("/user")
@Api(tags = "用户相关API接口")
@Slf4j
public class UserController {
    @Autowired
    private IUserService userService;
    @Autowired
    private CosController cosController;
    @Value("${custom-config.password}")
    private String password;

    public UserController() {
        log.info("【UserController】");
    }

    @PostMapping("/login")
    @ApiOperation(value = "用户登录")
    @ApiOperationSupport(order = 1)
    public R login(@Valid @RequestBody LoginForm form){
        // 将表单数据转换为HashMap
        HashMap param = JSONUtil.parse(form).toBean(HashMap.class);
        // 执行登录
        HashMap map = userService.login(param);
        // 获取用户id
        Long userId = MapUtil.getLong(map,"id");
        // 登录
        StpUtil.login(userId);
        // 获取用户权限
        ArrayList<String> permissions = userService.searchUserPermission(userId);
        // 获取token
        String token=StpUtil.getTokenInfo().getTokenValue();
        // 返回结果
        return  R.ok(map).put("msg","登录成功").put("token",token).put("permissions",permissions);
    }

    @PostMapping("/logout")
    @ApiOperation(value = "当前用户退出登录")
    @ApiOperationSupport(order = 2)
    @SaCheckLogin
    public R logout(){
        StpUtil.logout();
        return R.ok("退出登录");
    }
    @PostMapping("/setLogout")
    @ApiOperation(value = "强制指定账户退出登录")
    @ApiOperationSupport(order = 3)
    @SaCheckLogin
    public R setLogout(@Valid @RequestBody SetLogoutForm form){
        // 获取用户id
        Long userId = form.getId();
        if (StpUtil.isLogin()){
            // 获取当前用户id
            Long curId = StpUtil.getLoginIdAsLong();
            // 判断当前用户id是否与要退出的用户id相同
            if (curId.equals(userId)){
                return R.error("当前操作不能退出自己");
            }
        }
        StpUtil.logout(userId);
        return R.ok("已将该用户退出系统");
    }
    @PostMapping("/tokenTimeout")
    @ApiOperation(value = "获取当前用户的Token有效时间")
    @ApiOperationSupport(order = 4)
    public R tokenTimeOut(){
        return R.ok().put("ttl",StpUtil.getTokenTimeout());
    }
    @PostMapping("/register")
    @ApiOperation(value = "注册用户")
    @ApiOperationSupport(order = 5)
    public R register(@Valid @RequestBody RegisterForm form){
        // 判断是否存在相同的用户账户
        if (userService.selectUserByAccount(form.getAccount())!=null){
            return R.error("用户已经存在,注册失败");
        }
        // 将表单数据转换为User对象
        User user = JSONUtil.parse(form).toBean(User.class);
        // 设置密码
        user.setPassword(password);
        // 设置在职
        user.setIsIncumbency(false);
        //获取角色id
        Long[] roleIds = form.getRoleId();
        // 注册
        userService.register(user,roleIds);
        return R.ok("注册成功");
    }

    @PostMapping("/info")
    @ApiOperation(value = "获取当前用户信息")
    @ApiOperationSupport(order = 6)
    @SaCheckLogin
    public R getUserInfo(){
        Long id = Long.parseLong((String) StpUtil.getLoginId());
        // 查询用户信息
        HashMap user = userService.getUserInfo(id);
        // 返回结果
        return R.ok().put("userinfo",user);
    }
    @PostMapping("/valid/password")
    @ApiOperation(value = "验证原密码是否正确")
    @ApiOperationSupport(order = 7)
    @SaCheckLogin
    public R validPassword(@Valid @RequestBody ValidPasswordForm form){
        Long id = Long.parseLong((String) StpUtil.getLoginId());
        Boolean result = userService.validPassword(id,form.getPassword());
        if(result){
            return R.ok().put("result",result);
        }else {
            return R.error("原密码错误").put("result",result);
        }
    }
    @PutMapping("/update/password")
    @ApiOperation(value = "修改密码")
    @ApiOperationSupport(order = 8)
    @SaCheckLogin
    public R updatePassword(@Valid @RequestBody UpdatePasswordForm form){
        Long id = Long.parseLong((String) StpUtil.getLoginId());
        return R.ok("修改成功").put("result",userService.updatePassword(id,form.getPassword()));
    }
    @GetMapping("/account")
    @ApiOperation(value = "查询当前用户账号")
    @ApiOperationSupport(order = 9)
    @SaCheckLogin
    public R getAccount(){
        Long id = Long.parseLong((String) StpUtil.getLoginId());
        return R.ok().put("account",userService.getAccount(id));
    }
    @PutMapping("/update/account")
    @ApiOperation(value = "修改当前用户账号")
    @ApiOperationSupport(order = 10)
    @SaCheckLogin
    public R updateAccount(@Valid @RequestBody UpdateAccountForm form){
        Long id = Long.parseLong((String) StpUtil.getLoginId());
        return R.ok("修改成功").put("result",userService.updateAccount(id,form.getAccount()));
    }
    @GetMapping("/email")
    @ApiOperation(value = "查询当前用户邮箱")
    @ApiOperationSupport(order = 11)
    @SaCheckLogin
    public R getEmail(){
        Long id = Long.parseLong((String) StpUtil.getLoginId());
        return R.ok().put("email",userService.getEmail(id));
    }
    @PostMapping("/update/description")
    @ApiOperation(value = "修改当前用户自我介绍")
    @ApiOperationSupport(order = 12)
    @SaCheckLogin
    public R updateDescription(@RequestBody DescriptionForm form){
        Long id = Long.parseLong((String) StpUtil.getLoginId());
        return R.ok().put("result",userService.updateDescription(id,form.getDescription()));
    }
    @PostMapping("/update/motto")
    @ApiOperation(value = "修改当前用户座右铭")
    @ApiOperationSupport(order = 13)
    @SaCheckLogin
    public R updateMotto(@RequestBody MottoForm form){
        Long id = Long.parseLong((String) StpUtil.getLoginId());
        return R.ok().put("result",userService.updateMotto(id,form.getMotto()));
    }
    @PostMapping("/update/avater")
    @ApiOperation(value = "修改当前用户头像")
    @ApiOperationSupport(order = 14)
    @SaCheckLogin
    public R updateAvater(@RequestParam("files") MultipartFile[] files, @RequestParam("type") String type){
        Long id = Long.parseLong((String) StpUtil.getLoginId());
        HashMap res = cosController.uploadCosFile(files, type);
        if(res.get("code").equals(20000)){
            String json = JSONUtil.toJsonStr(res);
            JSONObject jsonObject = JSONUtil.parseObj(json);
            JSONObject result = jsonObject.getJSONObject("result");
            JSONArray urls = result.getJSONArray("urls");
            String url = urls.get(0).toString();
            Integer num = userService.updateAvater(id,url);
            if (num>0){
                return R.ok("修改成功").put("result",url);
            }else {
                return R.error("修改失败");
            }
        }else {
            return R.error("出现了一点问题");
        }
    }
    @PutMapping ("/update/avater_url")
    @ApiOperation(value = "修改当前用户头像路径")
    @ApiOperationSupport(order = 15)
    @SaCheckLogin
    public R updateAvaterUrl(@Valid @RequestBody AvaterUrlForm form){
        Long id = Long.parseLong((String) StpUtil.getLoginId());
        Integer num = userService.updateAvater(id,form.getUrl());
        if (num>0){
            return R.ok("修改成功").put("result",form.getUrl());
        }else {
            return R.error("修改失败");
        }
    }
    @PutMapping("/update/userInfo")
    @ApiOperation(value = "修改当前用户基本信息")
    @ApiOperationSupport(order = 16)
    @SaCheckLogin
    public R updateUserInfo(@Valid @RequestBody UpdateUserInfoForm form){
        Long id = Long.parseLong((String) StpUtil.getLoginId());
        userService.updateUserInfo(id,form);
        return R.ok("修改成功");
    }
    @PostMapping("")
    @ApiOperation("分页查询所有用户的列表")
    @ApiOperationSupport(order = 17)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "页码", defaultValue = "1", paramType = "query", dataType = "long"),
    })
    @SaCheckLogin
    public R getUserList(@Range(min = 1, message = "请提交有效的页码值！") Integer page){
        Integer pageNum = page == null ? 1 : page;
        PageData<UserInfoVo> pageData = userService.listUser(pageNum,Long.parseLong((String) StpUtil.getLoginId()));
        return R.ok().put("data",pageData);
    }

    @PostMapping("/resetPassword")
    @ApiOperation("重置指定用户密码")
    @ApiOperationSupport(order = 18)
    @SaCheckLogin
    public R resetPassword(@Valid @RequestBody ResetPasswordForm form){
        Long id = Long.parseLong((String) StpUtil.getLoginId());
        if(id.equals(form.getId())){
            return R.error("不能重置自己的密码");
        }
        if(userService.resetPassword(form.getId())){
            SetLogoutForm logoutForm = new SetLogoutForm();
            logoutForm.setId(form.getId());
            setLogout(logoutForm);
            return R.ok("重置成功");
        }
        return R.ok("重置成功");
    }

    @PostMapping("/searchByname")
    @ApiOperation("根据用户名搜索用户")
    @ApiOperationSupport(order = 19)
    @SaCheckLogin
    public R searchByname(@Valid @RequestBody SearchUserForm form){
        Integer pageNum = form.getPageNum() == null ? 1 : form.getPageNum();
        form.setPageNum(pageNum);
        PageData<UserInfoVo> pageData = userService.listSearchResult(form);
        return R.ok().put("data",pageData);
    }

    @PostMapping("/updateRegistration")
    @ApiOperation("根据用户id更新用户登记状态")
    @ApiOperationSupport(order = 20)
    @SaCheckLogin
    public R updateRegistration(@Valid @RequestBody UpdateRegistrationForm form){
        if(form.getId()==null){
            Long id = Long.parseLong((String) StpUtil.getLoginId());
            form.setId(id);
        }
        userService.updateRegistration(form);
        return R.ok();
    }

    @PostMapping("/groupOrgUserList")
    @ApiOperation("根据组织ids获取组织下的用户列表")
    @ApiOperationSupport(order = 21)
    @SaCheckLogin
    public R groupOrgUserList(@Valid @RequestBody GroupOrgUserListForm form){
        Integer pageNum = form.getPageNum() == null ? 1 : form.getPageNum();
        form.setPageNum(pageNum);
        form.setUserId(Long.parseLong((String) StpUtil.getLoginId()));
        PageData<UserInfoVo> pageData = userService.listgroupOrgUserList(form);
        return R.ok().put("data",pageData);
    }

    @PostMapping("/searchInOrganizationids")
    @ApiOperation("在组织id的情况下根据姓名搜索用户")
    @ApiOperationSupport(order = 22)
    @SaCheckLogin
    public R searchInOrganizationids(@Valid @RequestBody GroupOrgUserSearchForm form){
        Integer pageNum = form.getPageNum() == null ? 1 : form.getPageNum();
        form.setPageNum(pageNum);
        form.setUserId(Long.parseLong((String) StpUtil.getLoginId()));
        PageData<UserInfoVo> pageData = userService.searchInOrganizationids(form);
        return R.ok().put("data",pageData);
    }

    @PostMapping("/getAllUserList")
    @ApiOperation("管理员获取所有用户列表")
    @ApiOperationSupport(order = 23)
    @SaCheckLogin
    public R getAllUserList(@Valid @RequestBody GetAllUserListForm form){
        Integer pageNum = form.getPageNum() == null ? 1 : form.getPageNum();
        form.setPageNum(pageNum);
        form.setId(Long.parseLong((String) StpUtil.getLoginId()));
        PageData<UserInfoVo> pageData = userService.getAllUserList(form);
        return R.ok().put("data",pageData);
    }
    @PutMapping("/updateUserOrgAndPost")
    @ApiOperation("修改用户组织岗位")
    @ApiOperationSupport(order = 24)
    @SaCheckLogin
    public R updateUserOrgAndPost(@Valid @RequestBody UpdateUserOrgAndPostForm form){
        if(form.getId()==null){
            form.setId(Long.parseLong((String) StpUtil.getLoginId()));
        }
        userService.updateUserOrgAndPost(form);
        return R.ok();
    }

    @PostMapping("/setDimission")
    @ApiOperation("创建一条离职记录")
    @ApiOperationSupport(order = 25)
    @SaCheckLogin
    public R setTransfer(@Valid @RequestBody DimissiomForm form){
        if(form.getUserId()==null){
            form.setUserId(Long.parseLong((String) StpUtil.getLoginId()));
        }
        return R.ok().put("data",userService.setDimission(form));
    }

    @PutMapping("/updateUserDimission")
    @ApiOperation("修改用户为离职状态")
    @ApiOperationSupport(order = 26)
    @SaCheckLogin
    public R updateUserDimission(@Valid @RequestBody updateUserDimissionForm form){
        if(form.getId()==null) {
            form.setId(Long.parseLong((String) StpUtil.getLoginId()));
            if(form.getId().equals(1L)){
                return R.error("系统管理员无法离职");
            }
        }
        userService.updateUserDimission(form.getId());
        return R.ok();
    }

    @GetMapping("/searchUserContactList")
    @ApiOperation("查询通讯录列表")
    @ApiOperationSupport(order = 27)
    @SaCheckLogin
    public R searchUserContactList() {
        JSONObject json = userService.searchUserContactList();
        return R.ok().put("result", json);
    }

    @PostMapping("/getAllOutUserList")
    @ApiOperation("管理员获取所有离职用户列表")
    @ApiOperationSupport(order = 28)
    @SaCheckLogin
    public R getAllOutUserList(@Valid @RequestBody GetAllUserListForm form){
        Integer pageNum = form.getPageNum() == null ? 1 : form.getPageNum();
        form.setPageNum(pageNum);
        form.setId(Long.parseLong((String) StpUtil.getLoginId()));
        PageData<UserInfoVo> pageData = userService.getAllOutUserList(form);
        return R.ok().put("data",pageData);
    }

    @PostMapping("/getAllPeopleCount")
    @ApiOperation("获取所有用户数量")
    @ApiOperationSupport(order = 29)
    @SaCheckLogin
    public R getAllPeopleCount(){
        return R.ok().put("data",userService.getAllPeopleCount());
    }

    @PostMapping("/groupOrgOutUserList")
    @ApiOperation("根据组织ids获取组织下的离职用户列表")
    @ApiOperationSupport(order = 30)
    @SaCheckLogin
    public R groupOrgOutUserList(@Valid @RequestBody GroupOrgUserListForm form){
        Integer pageNum = form.getPageNum() == null ? 1 : form.getPageNum();
        form.setPageNum(pageNum);
        form.setUserId(Long.parseLong((String) StpUtil.getLoginId()));
        PageData<UserInfoVo> pageData = userService.listgroupOrgOutUserList(form);
        return R.ok().put("data",pageData);
    }
}
